home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Magnum One
/
Magnum One (Mid-American Digital) (Disc Manufacturing).iso
/
d13
/
nuf210.arc
/
NUFIND.C
< prev
next >
Wrap
Text File
|
1990-06-14
|
15KB
|
491 lines
/*----------------------------------------------------------------------*/
/* NUFIND.EXE - Enhanced MS DOS implementation of the Unix find
* command. NUFIND will find all files matching a set
* of specified criteria and perform any of several
* operations (move, copy, delete, etc.) on each file
* that matches the search criteria.
*
* Version: 2.1.0
* Date: June 13, 1990
* Author: Don A. Williams
*
********************* NOTICE ************************
* Contrary to the current trend in MS-DOS software *
* this program, for whatever it is worth, is NOT *
* copyrighted (with the exception of the runtime *
* library from the C compiler)! The program, in *
* whole or in part, may be used freely in any *
* fashion or environment desired. If you find this *
* program to be useful to you, do NOT send any *
* contribution to the author; in the words of Rick *
* Conn, 'Enjoy!' However, if you make any *
* improvements, I would enjoy receiving a copy of *
* the modified source. I can be reached, usually *
* within 24 hours, by messages on any of the *
* following Phoenix, AZ systems (the Phoenix systems *
* can all be reached through StarLink node #9532): *
* *
* The Tool Shop BBS [PCBOARD] [PC-Pursuit] *
* (602) 279-2673 1200/2400/9600 bps *
* Technoids Anonymous [PCBOARD] *
* (602) 899-4876 300/1200/2400 bps *
* (602) 899-5233 *
* (602) 786-9131 *
* Inn On The Park [PCBOARD] *
* (602) 957-0631 1200/2400/9600 bps *
* Pascalaholics Anonymous [WBBS] *
* (602) 484-9356 1200/2400 bps *
* *
* or: *
* Blue Ridge Express [RBBS] Richmond, VA *
* (804) 790-1675 2400 bps [StarLink #413] *
* *
* The Lunacy BBS [PCBOARD] Van Nuys, CA *
* (805) 251-7052 2400/9600 [StarLink 6295] *
* (805) 251-8637 2400/9600 [StarLink 6295] *
* *
* or: *
* GEnie, mail address: DON-WILL *
* CompuServ: 75410,543 *
* *
* Every effort has been made to avoid error and *
* moderately extensive testing has been performed *
* on this program, however, the author does not *
* warrant it to be fit for any purpose or to be *
* free from error and disclaims any liability for *
* actual or any other damage arising from the use *
* of this program. *
*******************************************************
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include <conio.h>
#include <dir.h>
#include <dos.h>
#include <io.h>
#include <sys\stat.h>
#include "nufind.h"
#include "queue.h"
struct DateSel {
unsigned Date;
int Swt;
};
QUE_DEF Paths, ExcPaths, IncNameQueue, ExcNameQueue;
QUE_DEF IncPathQueue, ExcPathQueue, NoCreateQ;
char ProgName[9];
char CurDir[66] = "";
char DestDir[66] = "";
char *CommandString;
int BaseLength = 0;
long TotalSize = 0L;
int RecurSwt = 1;
int PrtSwt = 1;
int LsSwt = 0;
int LdSwt = 0;
int RmSwt = 0;
int RmDirSwt = 0;
int RmSwtA = 0;
int AttrSwt = 0;
int NotAttrSwt = 0;
int AttrOnSwt = 0;
int AttrOffSwt = 0;
int CopySwt = 0;
int MoveSwt = 0;
int TreeSwt = 0;
int SizeSwt = 0;
int ExecSwt = 0;
int SumSwt = 0;
int RelSwt = 0;
int OldDate = 0;
struct DateSel Since = {0, 0};
struct DateSel Before = {0, 0};
char AttrMask = 0;
char NotAttrMask = 0;
char AttrOnMask = 0;
char AttrOffMask = 0;
long Size = 0;
char *ExistRef = NULL;
char *NotExistRef = NULL;
char *CompRef = NULL;
char *NotCompRef = NULL;
INFO_BLOCK *LT_Ref = NULL;
INFO_BLOCK *LE_Ref = NULL;
INFO_BLOCK *GT_Ref = NULL;
INFO_BLOCK *GE_Ref = NULL;
INFO_BLOCK *LT_DateRef = NULL;
INFO_BLOCK *LE_DateRef = NULL;
INFO_BLOCK *GT_DateRef = NULL;
INFO_BLOCK *GE_DateRef = NULL;
struct date Today;
unsigned TodayDate;
void GetProgName (char *Name, char *argv);
char *RootPath (char *CurDir, char *RelPath, char *FullPath);
void GetCurrentDisk (int *CurDisk);
int GetCurrentDirectory (int Disk, char *CurDir);
void GetArgs (char *argv[], int i);
void QueuePath (QUE_DEF *Q, char *Name);
void ProcessPaths (char *Name, int Level);
int Select (INFO_BLOCK *Name);
void Action (INFO_BLOCK *Name);
char *PrintNumber (long Number);
void Replace (char *Str1, int n, char *Str2);
void ErrorMsg (char *Format, ...);
void ExceptionMsg (char *Format, ...);
void ErrorExit (char *Format, ...);
void GetPath (QUE_DEF *Q, char *Arg);
char P_Name[70];
void
main (int argc, char *argv[]) {
int i;
int CurDisk;
QUE_ENTRY *t;
GetProgName(ProgName, argv[0]);
fprintf(stderr, "%s: NewUFind - Version %s: Date - %s\n", ProgName,
VERSION, VER_DATE);
getdate(&Today);
TodayDate = ( (Today.da_year - 1980) << 9) | (Today.da_mon << 5) | Today.da_day;
GetCurrentDisk(&CurDisk);
CurDir[0] = (char) (CurDisk + 'A'); CurDir[1] = ':'; CurDir[2] = '\\';
GetCurrentDirectory(0, CurDir+3);
strlwr(CurDir);
if (CurDir[strlen(CurDir)-1] != '\\') strcat(CurDir, "\\");
InitQueue(&Paths); InitQueue(&IncNameQueue); InitQueue(&ExcNameQueue);
InitQueue(&IncPathQueue); InitQueue(&ExcPathQueue);
InitQueue(&NoCreateQ);
for (i=1; i < argc && argv[i][0] != '-'; ++i) GetPath(&Paths, argv[i]);
GetArgs(argv, i);
if (Paths.Count == 0)
if ( (Enque(&Paths, CurDir)) == NULL)
ErrorExit("Insufficient memory for Path list.\n");
for (t=Paths.Head; t != NULL; t = t->Next) ProcessPaths(t->Body, 0);
if (SumSwt) printf("Total Size = %16s\n", PrintNumber(TotalSize));
}
void
QueuePath (QUE_DEF *Q, char *Name) {
char FullPath[66];
if (RootPath(CurDir, Name, FullPath) != NULL) {
if (FullPath[strlen(FullPath)-1] != '\\') strcat(FullPath, "\\");
if ( (Enque(Q, FullPath)) == NULL)
ErrorExit("Insufficient memory for Path list.\n");
}
}
void
ProcessPaths (char *Body, int Level) {
QUE_DEF *Dirs;
QUE_ENTRY *u, *v;
char Name[66], DirName[66];
struct ffblk DirBlk;
int Status, i;
INFO_BLOCK FileInfo;
for (u=ExcPaths.Head; u != NULL; u = u->Next)
if (!strcmp(Body, u->Body)) return;
if (!Level) BaseLength = strlen(Body);
if ( (Dirs = malloc(sizeof(QUE_DEF))) == NULL) {
ErrorMsg("Insufficient memory for directory list.\n");
return;
}
InitQueue(Dirs);
strcpy(Name, Body);
DirName[0] = '\0';
if ( (i = strlen(Name)) > 3 && Name[i-2] != ':' && Name[i-1] == '\\')
Name[i-1] = '\0';
if (Name[i-1] != '\\' && (Status = findfirst(Name, &DirBlk, 0xFF)) != 0)
return;
if ( Name[i-1] == '\\' || (DirBlk.ff_attrib & FA_DIREC) != 0 ) {
strcpy(DirName, Name);
if (Name[i-1] != '\\') strcat(Name, "\\");
strcat(Name, "*.*");
Status = findfirst(Name, &DirBlk, 0xFF);
while (Status == 0) {
strcpy(FileInfo.Name, Body);
strcat(FileInfo.Name, DirBlk.ff_name);
strlwr(FileInfo.Name);
FileInfo.Attrib = DirBlk.ff_attrib;
FileInfo.FTime.Time = DirBlk.ff_ftime;
FileInfo.FDate.Date = DirBlk.ff_fdate;
FileInfo.Size = DirBlk.ff_fsize;
if ( (DirBlk.ff_attrib & FA_DIREC) != 0 ) {
if (!strcmp(DirBlk.ff_name, "..")
|| !strcmp(DirBlk.ff_name, ".") ) {
Status = findnext(&DirBlk);
continue;
}
strcpy(Name, Body); strcat(Name, DirBlk.ff_name);
if ( (Enque(Dirs, Name)) == NULL) {
ErrorMsg("Insufficient memory for directory list.\n");
return;
}
if (Select(&FileInfo)) Action(&FileInfo);
}
else if ( (DirBlk.ff_attrib & FA_LABEL) != 0 );
else if (Select(&FileInfo)) Action(&FileInfo);
Status = findnext(&DirBlk);
}
if (RecurSwt && Dirs->Count != 0) {
u = Dirs->Head;
while (u != NULL) {
strcpy(Name, u->Body); strcat(Name, "\\");
strlwr(Name);
ProcessPaths(Name, Level + 1);
free(u->Body);
v = u->Next;
free(u);
u = v;
}
InitQueue(Dirs);
}
}
else {
strcpy(FileInfo.Name, Name);
FileInfo.Attrib = DirBlk.ff_attrib;
FileInfo.FTime.Time = DirBlk.ff_ftime;
FileInfo.FDate.Date = DirBlk.ff_fdate;
FileInfo.Size = DirBlk.ff_fsize;
if (Select(&FileInfo)) Action(&FileInfo);
}
if (RmDirSwt && DirName[0] != '\0' ) {
if (DirName[strlen(DirName)-2] == ':') return;
printf("RMDIR: %s\n", DirName);
CurDir[strlen(CurDir)-1] = '\0';
if (!strcmp(DirName, CurDir)) {
*(strrchr(CurDir, '\\')) = '\0';
chdir(CurDir);
}
strcat(CurDir, "\\");
if (rmdir(DirName)) perror(" FAILED");
}
}
void
GetProgName (char *Name, char *argv) {
char *p, *p1;
if ( (p = strrchr(argv, '\\')) != NULL) ++p;
else p = argv;
if ( (p1 = strchr(p, '.')) != NULL) *p1 = '\0';
strcpy(Name, p);
}
/****************************************************************************
* PrintNumber -- Print a long number, inserting ","s where needed.
****************************************************************************/
char *
PrintNumber (long Number) {
static char Temp[20];
int l, i;
sprintf(Temp, "%lu", Number);
l = strlen(Temp);
for (i=0; i < l; ++i) {
if ( i && ((i) % 3) == 0) {
memmove(&Temp[l-i+1], &Temp[l-i], strlen(&Temp[l-i])+1);
Temp[l-i] = ',';
}
}
return(Temp);
}
void
ErrorExit (char *Format, ...) {
va_list ArgPtr;
extern char ProgName[];
extern int errno;
fprintf(stderr, "%s: ", ProgName);
va_start(ArgPtr, Format);
vfprintf(stderr, Format, ArgPtr);
va_end(ArgPtr);
if (errno) perror(" ");
fprintf(stderr, "\n");
exit(1);
}
void
Execute (char *Name) {
extern char *CommandString;
char *Command, Dir[65], FName[9];
char *q, *p1, *p2;
int n;
if ( (Command = malloc(129)) == NULL) {
ErrorMsg("Insufficient memory for command.\n");
return;
}
strcpy(Command, CommandString);
n = 0;
while ( (q = strchr(&Command[n], '%')) != NULL ) {
switch(toupper(*(q+1))) {
case 'F':
p1 = strrchr(Name, '\\');
Replace(q, 2, ++p1);
break;
case 'P':
Replace(q, 2, Name);
break;
case 'N':
p1 = strrchr(Name, '\\');
p2 = strchr(++p1, '.');
strncpy(FName, p1, (int) (p2 - p1) );
FName[(int) (p2 - p1)] = '\0';
Replace(q, 2, FName);
break;
case 'E':
p1 = strrchr(Name, '.');
Replace(q, 2, ++p1);
break;
case 'D':
p1 = strrchr(Name, '\\');
strncpy(Dir, Name, (int) (p1 - Name) );
Dir[(int) (p1 - Name)] = '\0';
Replace(q, 2, Dir);
break;
}
n = (int) (q - Command) + 2;
}
system(Command);
free(Command);
}
/**************************************************************************
* Replace - Replaces a number of characters equal to the length of Str2
* in Str1 with the contents of Str2. The position is Str1 is
* specified by n.
*************************************************************************/
void
Replace (char *Str1, int n, char *Str2) {
int l, r;
l = strlen(Str1);
r = strlen(Str2);
memmove(&Str1[r], &Str1[n], l - n + 1);
strncpy(Str1, Str2, r);
}
void
ErrorMsg (char *Format, ...) {
va_list ArgPtr;
extern char ProgName[];
extern int errno;
fprintf(stderr, "%s: - ", ProgName);
va_start(ArgPtr, Format);
vfprintf(stderr, Format, ArgPtr);
va_end(ArgPtr);
if (errno) perror(" ");
fprintf(stderr, "\n");
}
void
ExceptionMsg (char *Format, ...) {
va_list ArgPtr;
fprintf(stderr, " ");
va_start(ArgPtr, Format);
vprintf(Format, ArgPtr);
va_end(ArgPtr);
fputc('\n', stdout);
if (errno) {
perror(" ");
fputc('\n', stdout);
}
}
int
GetYorN (char *Message, ...) {
va_list ArgPtr;
char Reply;
while (1) {
va_start(ArgPtr, Message);
fprintf(stderr, " ");
vfprintf(stderr, Message, ArgPtr);
fprintf(stderr, "('Y', 'N' or A)bort)? ");
Reply = toupper(getch());
if (Reply == 'A') exit(1);
if (Reply == 'Y' || Reply == 'N') break;
fprintf(stderr, "%c is invalid.\n \007", Reply);
}
va_end(ArgPtr);
fprintf(stderr, "%c\n", Reply);
return( (Reply == 'Y') );
}
void
GetPath (QUE_DEF *Q, char *Arg) {
extern char P_Name[70];
char *p, Temp[65];
int i, j;
CurDir[strlen(CurDir)-1] = '\0';
if ( !strcmp(Arg, ".") ) strcpy(P_Name, CurDir);
else if ( !strcmp(Arg, "..") ) {
p = strrchr(CurDir, '\\');
*p = '\0';
strcpy(P_Name, CurDir);
*p = '\\';
}
else strcpy(P_Name, Arg);
strcat(CurDir, "\\");
if ( (p = strchr(P_Name, ':')) != NULL) {
if ( (i = (int) (p - P_Name) ) > 1) {
for (j=0; j < i; ++j) {
Temp[0] = P_Name[j];
Temp[1] = '\0';
strcat(Temp, p);
if (Temp[strlen(Temp)-1] != '\\') strcat(Temp, "\\");
if (Enque(Q, Temp) == NULL)
ErrorExit("Insufficient memory for Path List.\n");
}
}
else {
strcpy(Temp, P_Name);
if (Temp[strlen(Temp)-1] != '\\') strcat(Temp, "\\");
if (Enque(Q, Temp) == NULL)
ErrorExit("Insufficient memory for Path List.\n");
}
}
else {
Temp[0] = CurDir[0]; Temp[1] = ':'; Temp[2] = '\0';
strcat(Temp, P_Name);
if (Temp[strlen(Temp)-1] != '\\') strcat(Temp, "\\");
if (Enque(Q, Temp) == NULL)
ErrorExit("Insufficient memory for Path List.\n");
}
}